package com.zkyt.lib_msdk_ext.component

import android.util.Log
import com.geoai.mavlink.geoainet.airlink.AirlinkManager
import com.geoai.mavlink.geoainet.airlink.enums.CellularEnhancedTransmissionType
import com.geoai.mavlink.geoainet.airlink.enums.CellularServerConnectState
import com.geoai.mavlink.geoainet.airlink.info.CellularQualityInfo
import com.geoai.mavlink.geoainet.airlink.info.CellularServerConnectionInfo
import com.geoai.mavlink.geoainet.airlink.info.CellularSignalInfo
import com.geoai.mavlink.geoainet.airlink.info.WirelessSignalInfo
import com.geoai.mavlink.geoainet.airlink.interfaces.IBaseCellularListener
import com.geoai.mavlink.geoainet.airlink.interfaces.IBaseDspListener
import com.geoai.mavlink.geoainet.base.mavlinkcore.engine.GEOAIError
import com.geoai.mavlink.geoainet.base.mavlinkcore.interfaces.CompletionCallback.ICompletionCallbackWith
import com.geoai.mavlink.geoainet.flycontroller.enums.AircraftFailSafeBehaviorMode
import com.zkyt.lib_msdk_ext.common.CallbackWithRxHandler
import com.zkyt.lib_msdk_ext.common.CompletionCbRxHandler
import com.zkyt.lib_msdk_ext.common.SDKExceptionWrapper
import com.zkyt.lib_msdk_ext.common.SDKExtUtil
import com.zkyt.lib_msdk_ext.log.SDKExtLog
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.subjects.BehaviorSubject
import java.util.Optional

/**
 * Created by chenyu on 2024/1/18
 * Description: 地面端airLink的扩展。
 *
 * 注意，以后要限制这个类，只处理地面端的airLink，不要和天空端的业务耦合。生命周期不一样。
 */
object AirLinkManagerExt: ISDKExt<IBaseDspListener>, IRemovableComp {
    private val isConnectSubject = BehaviorSubject.createDefault(false)
    private var airLinkManager: IBaseDspListener? = null
    private var cellularManager: IBaseCellularListener? = AirlinkManager.getInstance().cellular
    private val orgWirelessSignalInfoSubject =
        BehaviorSubject.createDefault(Optional.empty<WirelessSignalInfo>())
    private val orgCellularVideoQualityInfoSubject =
        BehaviorSubject.createDefault(Optional.empty<CellularQualityInfo>())
    private val orgCellularSignalInfoSubject =
        BehaviorSubject.createDefault(Optional.empty<CellularSignalInfo>())

    override fun init(originManager: IBaseDspListener) {
        airLinkManager = originManager

        airLinkManager?.setWirelessSignalQualityListener {
            orgWirelessSignalInfoSubject.onNext(Optional.of(it))
        }
        cellularManager?.setVideoChannelQualityListener {
            orgCellularVideoQualityInfoSubject.onNext(Optional.of(it))
        }
        cellularManager?.setSignalLevelListener {
            orgCellularSignalInfoSubject.onNext(Optional.of(it))
        }
        isConnectSubject.onNext(true)

        SDKExtLog.i("AirLinkManagerExt", "init()")
    }

    override fun isConnected(): Boolean {
        return isConnectSubject.value!!
    }

    override fun getConnectedObservable(): Observable<Boolean> {
        return isConnectSubject.hide()
    }

    override fun destroy() {
        isConnectSubject.onNext(false)
        airLinkManager?.setWirelessSignalQualityListener(null)
        orgWirelessSignalInfoSubject.onNext(Optional.empty())
        orgCellularVideoQualityInfoSubject.onNext(Optional.empty())
        orgCellularSignalInfoSubject.onNext(Optional.empty())
        airLinkManager = null

        SDKExtLog.i("AirLinkManagerExt", "destroy()")
    }

    override fun getOriginManager(): IBaseDspListener? {
        return airLinkManager
    }

    fun getWirelessSignalInfoObservable(): Observable<Optional<WirelessSignalInfo>> {
        return orgWirelessSignalInfoSubject.hide()
    }

    fun getCellularVideoQualityObservable(): Observable<Optional<CellularQualityInfo>> {
        return orgCellularVideoQualityInfoSubject.hide()
    }

    fun getCellularSignalObservable(): Observable<Optional<CellularSignalInfo>> {
        return orgCellularSignalInfoSubject.hide()
    }

    fun startPairingRx(): Completable {
        return Completable.create {
            airLinkManager?.startPairing(CompletionCbRxHandler(it))
        }
    }

    fun getCellularStatusRx(): Single<CellularServerConnectionInfo> {
        return Single.create { emitter ->
            cellularManager?.getCellularConnectionState(object : ICompletionCallbackWith<CellularServerConnectionInfo> {
                override fun onFailure(error: GEOAIError?) {
                    emitter.onError(SDKExceptionWrapper(error!!))
                }

                override fun onResult(result: CellularServerConnectionInfo?) {
                    emitter.onSuccess(result!!)
                }
            })
        }
    }

    fun setCellularModeRx(mode: CellularEnhancedTransmissionType): Completable {
        return Completable.create { emitter ->
            cellularManager?.setCellularEnhancedTransmissionType(mode
            ) { geoaiError ->
                SDKExtUtil.handleError(emitter, geoaiError)
            }
        }
    }

    fun getCellularModeRx(): Single<CellularEnhancedTransmissionType> {
        return Single.create { emitter ->
            cellularManager?.getCellularEnhancedTransmissionType(CallbackWithRxHandler(emitter))
        }
    }
}